package com.liangtian.mdm.material.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.liangtian.mdm.base.dao.JdbcDao;
import com.liangtian.mdm.base.utils.ShiroSessionUtils;
import com.liangtian.mdm.material.dao.WlLbmbtzlqzDao;
import com.liangtian.mdm.material.model.WlLbmbtzlqz;
import com.liangtian.mdm.material.service.WlLbmbtzlqzService;
import com.liangtian.mdm.system.user.model.SysUser;
import com.liangtian.mdm.system.user.util.ExcelImport;
import com.liangtian.mdm.util.ConstantBean;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class WlLbmbtzlqzServiceImpl implements WlLbmbtzlqzService {

    @Autowired
    private WlLbmbtzlqzDao wlLbmbtzlqzDao;
    @Autowired
    private JdbcDao jdbcDao;

    private ExcelImport excelImport = new ExcelImport();

    // Session中保存的当前登录用户的信息
    //@Value("${ConstantBean.CURRENT_SESSION_USER}")
    //private String ConstantBean.CURRENT_SESSION_USER;

    @SuppressWarnings({"rawtypes", "unchecked"})
    @Override
    public PageInfo getWlLbmbtzlqzListByCond(Map<String, Object> map) {
        PageInfo<List<WlLbmbtzlqz>> pageInfo = null;
        try {
            Object pNo = map.get("pageNum");
            int pageNum, pageSize;
            // export
            if (pNo != null && !"NaN".equals(pNo)) {
                pageNum = Integer.parseInt(pNo.toString());// 页码
            } else {
                pageNum = 1;
            }
            // pageSize=0时不分页
            pageSize = Integer.parseInt(map.get("limit").toString());// 模型定义页面要显示数据条数
            // 例如
            // 10,20,50,100
            PageHelper.startPage(pageNum, pageSize);// 开始分页标志（当前页，显示条数）

            List<WlLbmbtzlqz> list = wlLbmbtzlqzDao.getWlLbmbtzlqzListByCond2(map);
            pageInfo = new PageInfo(list);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return pageInfo;
    }

    @Override
    public int getWlLbmbtzlqzListCountByCond(WlLbmbtzlqz wlLbmbtzlqz) {
        return wlLbmbtzlqzDao.getWlLbmbtzlqzListCountByCond(wlLbmbtzlqz);
    }

    @Override
    public void updateWlLbmbtzlqz(WlLbmbtzlqz wlLbmbtzlqz) {
        wlLbmbtzlqzDao.updateWlLbmbtzlqz(wlLbmbtzlqz);

    }

    @Override
    public int insertWlLbmbtzlqz(WlLbmbtzlqz wlLbmbtzlqz) {
        return wlLbmbtzlqzDao.insertWlLbmbtzlqz(wlLbmbtzlqz);
    }

    @Override
    public List<WlLbmbtzlqz> getWlLbmbtzlqzListByCond(WlLbmbtzlqz wlLbmbtzlqz) {
        return wlLbmbtzlqzDao.getWlLbmbtzlqzListByCond(wlLbmbtzlqz);
    }

    @Override
    public WlLbmbtzlqz getWlLbmbtzlqzById(WlLbmbtzlqz wlLbmbtzlqz) {
        return wlLbmbtzlqzDao.getWlLbmbtzlqzById(wlLbmbtzlqz);
    }

    @Override
    public int getCountWlLbmbTzlQzByCond(WlLbmbtzlqz wlLbmbtzlqz) {
        Map<String, Object> map = new HashMap<>();
        map.put("qz", wlLbmbtzlqz.getQz());
        map.put("xh", wlLbmbtzlqz.getXh());
        map.put("id", wlLbmbtzlqz.getId());
        map.put("wl_lbmbtzl_id", wlLbmbtzlqz.getWl_lbmbtzl_id());
        return wlLbmbtzlqzDao.getCountWlLbmbTzlQzByCond(map);
    }

    @Override
    public int updateWlLbmbtzlqzByMap(Map<String, Object> map) {
        return wlLbmbtzlqzDao.updateWlLbmbtzlqzByMap(map);
    }

    @Override
    public int updateWlLbmbtzlqzByMbtzlidMap(Map<String, Object> map) {
        return wlLbmbtzlqzDao.updateWlLbmbtzlqzByMbtzlidMap(map);
    }

    @Override
    public List<WlLbmbtzlqz> getGlQzListByCond(Map<String, Object> cond) {
        return wlLbmbtzlqzDao.getGlQzListByCond(cond);
    }

    @Override
    @SuppressWarnings({"static-access", "resource"})
    public Map<String, Object> tzlqzImport(InputStream inputStream, String tzl_id) {
        Map<String, Object> result = new HashMap<>();
        String info = "";//记录错误信息
        boolean success = true;
        try {
            //读取excel
            Workbook wb = new XSSFWorkbook(inputStream);
            Sheet sheet = wb.getSheetAt(0);
            List<Object[]> valueList = excelImport.read(sheet);
            valueList.remove(0);//去掉表头

            //校验数据
            List<WlLbmbtzlqz> list = new ArrayList<WlLbmbtzlqz>();
            info = checkTzlqzImport(valueList, list, tzl_id);
            if (!StringUtils.isEmpty(info)) {
                success = false;
            }
            //2018-01-04修改  当前批次数据如果出现错误就不写入数据库
            if (!CollectionUtils.isEmpty(list) && success)
                insert(list);
        } catch (IOException e) {
            success = false;
        } catch (InvalidFormatException e) {
            success = false;
        }

        result.put("success", success);
        result.put("info", info);
        return result;
    }

    public String checkTzlqzImport(List<Object[]> valueList, List<WlLbmbtzlqz> list, String tzl_id) {
        StringBuffer sb = new StringBuffer();//存放错误信息
        if (!CollectionUtils.isEmpty(valueList)) {
            Map<String, String> tzlqz_map = new HashMap<String, String>();
            int currentError = 0;//超过一定错误数量不在继续校验

            for (int i = 0; i < valueList.size(); i++) {
                boolean flag = true;//标识当前excel行中数据是否正确
                if (currentError >= 20)
                    break;

                String errorRowInfo = "第" + (i + 2) + "行";
                String[] obj = (String[]) valueList.get(i);
                String tzlqz = obj[0];//特征量取值
                String tzlsm = obj[1];//特征量说明

                if (StringUtils.isEmpty(tzlqz)) {
                    sb.append(errorRowInfo + "特征量取值不能为空;\r\n");
                    currentError++;
                    flag = false;
                } else {
                    WlLbmbtzlqz qz = new WlLbmbtzlqz();
                    qz.setQz(tzlqz);
                    qz.setWl_lbmbtzl_id(tzl_id);
                    int count = this.getWlLbmbtzlqzListCountByCond(qz);
                    if (count > 0) {
                        sb.append(errorRowInfo + "特征量取值已存在;\r\n");
                        currentError++;
                        flag = false;
                    }
                }
                //校验excel中是否存在重复数据
                if (flag) {
                    String tzl_key = tzlqz;
                    String value = tzlqz_map.get(tzl_key);
                    if (null == value)
                        tzlqz_map.put(tzl_key, i + 2 + "");
                    else {
                        sb.append(errorRowInfo + "与第" + value + "行数据重复!\r\n");
                        currentError++;
                        flag = false;
                    }
                }
                if (flag) {
                    // 获取session中用户
                    SysUser user = ShiroSessionUtils.getSessionSysUser(ConstantBean.CURRENT_SESSION_USER);
                    WlLbmbtzlqz wlLbmbtzlqz = new WlLbmbtzlqz();
                    wlLbmbtzlqz.setWl_lbmbtzl_id(tzl_id);
                    wlLbmbtzlqz.setQz(tzlqz);
                    wlLbmbtzlqz.setSm(tzlsm);
                    //wlLbmbtzlqz.setCreate_time(new Date());
                    wlLbmbtzlqz.setCreator_name(user.getUserName());
                    wlLbmbtzlqz.setCreator_id(user.getUserAccount());
                    list.add(wlLbmbtzlqz);
                }
            }
        } else {
            sb.append("请在模板中填写需要导入的数据！\r\n");
        }

        return sb.toString();
    }

    private void insert(List<WlLbmbtzlqz> list) {
        StringBuilder sql = new StringBuilder();
        StringBuilder sqlForm = new StringBuilder();
        StringBuilder head = this.sqlHeadInsert();
        StringBuilder sqlHead = new StringBuilder(head);
        int batchCount = 1000;// 每批commit的个数
        int batchLastIndex = batchCount;// 每批最后一个的下标

        if (list.size() < batchCount) {
            for (int i = 0; i < list.size(); i++) {
                WlLbmbtzlqz tzlqz = list.get(i);
                sql = insertImportBatch(tzlqz);
                if (i != list.size() - 1) {
                    sql.append(" union ");
                }
                sqlForm.append(sql);
            }
            sqlHead.append(sqlForm);
            jdbcDao.executeSql(sqlHead.toString());
            sqlHead = new StringBuilder(head);
            sqlForm = new StringBuilder();
        } else {
            for (int index = 0; index < list.size(); ) {
                List<WlLbmbtzlqz> partRes = list.subList(index, batchLastIndex);
                for (int i = 0; i < partRes.size(); i++) {
                    WlLbmbtzlqz tzlqz = partRes.get(i);
                    sql = insertImportBatch(tzlqz);
                    if (i != partRes.size() - 1) {
                        sql.append(" union ");
                    }
                    sqlForm.append(sql);
                    continue;
                }
                sqlHead.append(sqlForm);
                jdbcDao.executeSql(sqlHead.toString());
                sqlHead = new StringBuilder(head);
                sqlForm = new StringBuilder();
                index = batchLastIndex;// 设置下一批下标
                batchLastIndex = index + (batchCount);//15 20 20  21
                if (batchLastIndex > list.size()) {
                    batchLastIndex = list.size();
                }
            }
        }

    }

    private StringBuilder sqlHeadInsert() {
        StringBuilder sqlHeader = new StringBuilder();
        sqlHeader.append("insert into wl_lbmb_tzlqz (id,wl_lbmbtzl_id,qz,sm,status,creator_id,creator_name,create_time,version)");
        return sqlHeader;
    }

    private StringBuilder insertImportBatch(WlLbmbtzlqz tzlqz) {
        StringBuilder sqlValues = new StringBuilder();
        sqlValues.append(" select ");
        sqlValues.append("get_seq('WL_LBMB_TZLQZ_SEQ')").append(",");
        sqlValues.append("'").append(tzlqz.getWl_lbmbtzl_id()).append("',");
        sqlValues.append("'").append(tzlqz.getQz()).append("',");
        sqlValues.append("'").append(tzlqz.getSm()).append("',");
        sqlValues.append("'1',");
        sqlValues.append("'").append(tzlqz.getCreator_id()).append("',");
        sqlValues.append("'").append(tzlqz.getCreator_name()).append("',");
        sqlValues.append("sysdate,");
        sqlValues.append("0");
        sqlValues.append(" from dual");
        return sqlValues;
    }

}
